package mgr

// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"

	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/ferror"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/gorms"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/resultcode"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/scalars"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/xids"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/enums"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/gqlgen/mgr/gmodel"
	"gitee.com/shiqiyue/xd-bi/internal/modules/cr/model"
	"gitee.com/shiqiyue/xd-bi/pkg/strings"
	"gorm.io/gorm/clause"
)

func (r *queryResolver) ReportDetail(ctx context.Context, reportID string) (*model.Report, error) {
	db := gorms.GetDb(ctx, r.Db)
	report := &model.Report{}
	err := r.ReportSrv.GetByUnionId(ctx, db, reportID, report)
	if err != nil {
		return nil, err
	}
	return report, nil
}

func (r *queryResolver) ReportPage(ctx context.Context, req gmodel.ReportPageReq) (*gmodel.ReportPageResp, error) {
	db := gorms.GetDb(ctx, r.Db)
	var dest []*model.Report
	simpleWhere := &gorms.SimpleWhere{Items: []gorms.SimpleWhereItem{}}
	if req.Code != nil {
		simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
			Column:  "code",
			Operate: gorms.OPERATE_LIKE,
			Value:   "%" + *req.Code + "%",
		})
	}
	if req.Name != nil {
		simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
			Column:  "name",
			Operate: gorms.OPERATE_LIKE,
			Value:   "%" + *req.Name + "%",
		})
	}
	simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
		Column:  "status",
		Operate: gorms.OPERATE_EQ,
		Value:   enums.REPORT_STATUS_ACTIVE,
	})
	// 排序
	orderBy := ""
	if req.OrderColumn != nil && *req.OrderColumn != "" {
		orderBy = strings.Camel2Case(*req.OrderColumn)
		if *req.OrderBy == "descending" {
			orderBy = orderBy + " desc"
		} else {
			orderBy = orderBy + " asc"
		}
	} else {
		orderBy = "id desc"
	}
	pageResult, err := r.ReportSrv.PageByParams(ctx, db, simpleWhere, &gorms.Param{
		Page:    req.CurrentPage,
		Limit:   req.PageSize,
		OrderBy: []string{orderBy},
	}, &dest)
	if err != nil {
		return nil, err
	}
	return &gmodel.ReportPageResp{
		TotalRecord: pageResult.TotalRecord,
		Records:     dest,
	}, nil
}

func (r *queryResolver) ReportList(ctx context.Context, req gmodel.ReportListReq) ([]*model.Report, error) {
	db := gorms.GetDb(ctx, r.Db)
	var dest []*model.Report
	simpleWhere := &gorms.SimpleWhere{Items: []gorms.SimpleWhereItem{}}
	if req.Code != nil {
		simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
			Column:  "code",
			Operate: gorms.OPERATE_LIKE,
			Value:   "%" + *req.Code + "%",
		})
	}
	if req.Type != nil {
		simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
			Column:  "type",
			Operate: gorms.OPERATE_EQ,
			Value:   req.Type,
		})
	}
	if req.DisplayType != nil {
		simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
			Column:  "display_type",
			Operate: gorms.OPERATE_IN,
			Value:   req.DisplayType,
		})
	}
	simpleWhere.Items = append(simpleWhere.Items, gorms.SimpleWhereItem{
		Column:  "status",
		Operate: gorms.OPERATE_EQ,
		Value:   enums.REPORT_STATUS_ACTIVE,
	})

	err := r.ReportSrv.ListByParams(ctx, db, simpleWhere, &dest)
	if err != nil {
		return nil, ferror.WrapWithCode("查询报表异常", resultcode.FAIL, err)
	}
	return dest, nil
}

func (r *queryResolver) ReportDetailByCode(ctx context.Context, code string) (*model.Report, error) {
	db := gorms.GetDb(ctx, r.Db)
	report := &model.Report{}
	err := r.ReportSrv.GetByCode(ctx, db, code, report)
	if err != nil {
		return nil, ferror.WrapWithCode("获取报表信息异常", resultcode.FAIL, err)
	}
	return report, nil
}

func (r *queryResolver) ReportAPI(ctx context.Context, reportID string) (*gmodel.ReportAPIResult, error) {
	db := gorms.GetDb(ctx, r.Db)
	// 获取报表信息
	report := model.Report{}
	err := r.ReportSrv.GetByUnionId(ctx, db, reportID, &report)
	if err != nil {
		return nil, ferror.WrapWithCode("获取报表信息异常", resultcode.FAIL, err)
	}
	reportApiItems, err := r.ReportSrv.GetReportAPI(ctx, db, report)
	if err != nil {
		return nil, ferror.WrapWithCode("获取API异常", resultcode.FAIL, err)
	}
	apiItems := []*gmodel.ReportAPIItem{}
	apiItems = append(apiItems, &gmodel.ReportAPIItem{
		ID:            scalars.GetStringRef(xids.GetXid(ctx)),
		AttributeName: scalars.GetStringRef("msg"),
		Name:          scalars.GetStringRef("返回信息"),
		Type:          scalars.GetStringRef("String"),
		Children:      nil,
	})
	apiItems = append(apiItems, &gmodel.ReportAPIItem{
		ID:            scalars.GetStringRef(xids.GetXid(ctx)),
		AttributeName: scalars.GetStringRef("code"),
		Name:          scalars.GetStringRef("编号"),
		Type:          scalars.GetStringRef("String"),
		Children:      nil,
	})
	apiItems = append(apiItems, &gmodel.ReportAPIItem{
		ID:            scalars.GetStringRef(xids.GetXid(ctx)),
		AttributeName: scalars.GetStringRef("data"),
		Name:          scalars.GetStringRef("数据"),
		Type:          scalars.GetStringRef("Object"),
		Children:      reportApiItems,
	})
	bs, err := json.Marshal(apiItems)
	if err != nil {
		return nil, ferror.WrapWithCode("序列化JSON异常", resultcode.FAIL, err)
	}
	str := string(bs)
	params, err := r.ReportSrv.GetParamByReportId(ctx, db, report)
	if err != nil {
		return nil, ferror.WrapWithCode("获取报表请求参数异常", resultcode.FAIL, err)
	}
	return &gmodel.ReportAPIResult{
		ResultStr:           str,
		RequestReportParams: params,
		Report:              &report,
	}, nil
}

func (r *queryResolver) Version(ctx context.Context, v int) (int, error) {
	return v + 2010, nil
}

func (r *queryResolver) ExportAPIMarkdown(ctx context.Context, ids []string) (*string, error) {
	mdBs := bytes.Buffer{}
	// api说明
	mdBs.WriteString(fmt.Sprintf("# 接口说明 \n"))
	mdBs.WriteString("- 请求URL \n")
	mdBs.WriteString(fmt.Sprintf("`%s` \n", "http://120.37.177.122:14002"))
	mdBs.WriteString("- 请求方式 \n")
	mdBs.WriteString("`HTTP请求` \n")
	mdBs.WriteString("- 请求头参数 \n")
	mdBs.WriteString("| 参数名 | 类型 | 说明 | \n")
	mdBs.WriteString("| ------------- | ------ | ------------------------------- | \n")
	mdBs.WriteString(fmt.Sprintf("| %s | %s | %s | \n", "Authorization", "String", "用户登录成功返回的令牌"))

	for _, id := range ids {
		api, err := r.ReportAPI(ctx, id)
		if err != nil {
			return nil, err
		}
		md, err := r.ReportSrv.ApiToMd(ctx, api)
		if err != nil {
			return nil, err
		}
		mdBs.WriteString(md)
	}
	md := mdBs.String()
	return &md, nil
}

func (r *reportResolver) SQLReport(ctx context.Context, obj *model.Report) (*model.SqlReport, error) {
	db := gorms.GetDb(ctx, r.Db)
	if obj == nil {
		return nil, nil
	}
	if obj.ReportId == "" {
		return nil, nil
	}
	return r.SqlReportSrv.GetByReportId(ctx, db, obj.ReportId)
}

func (r *reportResolver) ReportForms(ctx context.Context, obj *model.Report) ([]*model.ReportForm, error) {
	db := gorms.GetDb(ctx, r.Db)
	forms, err := r.ReportSrv.GetFormByReportId(ctx, db, obj.ReportId)
	res := make([]*model.ReportForm, 0)
	if forms != nil {
		for i, _ := range forms {
			res = append(res, &forms[i])
		}
	}
	return res, err
}

func (r *reportResolver) ReportResultColumns(ctx context.Context, obj *model.Report) ([]*model.ReportResultColumn, error) {
	db := gorms.GetDb(ctx, r.Db)
	if obj == nil {
		return nil, nil
	}
	db = db.Preload(clause.Associations)
	resultColumns, err := r.ReportResultColumnSrv.GetByReportId(ctx, db, obj.ReportId)
	if err != nil {
		return nil, err
	}
	var res []*model.ReportResultColumn
	for i := range resultColumns {
		res = append(res, &resultColumns[i])
	}
	return res, nil
}

func (r *reportResolver) ReportParams(ctx context.Context, obj *model.Report) ([]*gmodel.ReportParam, error) {
	db := gorms.GetDb(ctx, r.Db)
	params, err := r.ReportSrv.GetParamByReportId(ctx, db, *obj)
	if err != nil {
		return nil, ferror.Wrap("获取报表PARAM失败", err)
	}
	// 如果支持数据权限，则返回数据权限的参数
	if obj.DataAccessSupport {
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_UserId",
			Name:          "数据权限-用户ID",
			Type:          enums.REPORT_PARAM_TYPE_TEXT,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_DepartmentIds",
			Name:          "数据权限-部门ID列表",
			Type:          enums.REPORT_PARAM_TYPE_TEXT_ARRAY,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_OrganizationIds",
			Name:          "数据权限-组织ID列表",
			Type:          enums.REPORT_PARAM_TYPE_TEXT_ARRAY,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_OrganizationIds_array",
			Name:          "数据权限-组织ID列表(pg数组格式)",
			Type:          enums.REPORT_PARAM_TYPE_TEXT_ARRAY,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_ProvinceId",
			Name:          "数据权限-省ID",
			Type:          enums.REPORT_PARAM_TYPE_TEXT,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_CityId",
			Name:          "数据权限-市ID",
			Type:          enums.REPORT_PARAM_TYPE_TEXT,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_AreaId",
			Name:          "数据权限-区ID",
			Type:          enums.REPORT_PARAM_TYPE_TEXT,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "auths_DataAccess",
			Name:          "数据权限,1-全部,2-省,3-市,4-县,5-组织,6-部门,7-个人,8-管理部门",
			Type:          enums.REPORT_PARAM_TYPE_NUMBER,
		})
	}
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_UserId",
		Name:          "登录用户-用户ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_DepartmentId",
		Name:          "登录用户-部门ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_OrganizationId",
		Name:          "登录用户-组织ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_ProvinceId",
		Name:          "登录用户-省份ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_CityId",
		Name:          "登录用户-城市ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_DistrictId",
		Name:          "登录用户-区县ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_RoleId",
		Name:          "登录用户-角色ID",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_AgentIds",
		Name:          "登录用户-绑定的代理商ID列表",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	params = append(params, &gmodel.ReportParam{
		AttributeName: "user_SateliteOperatorIds",
		Name:          "登录用户-绑定的卫星运营商ID列表",
		Type:          enums.REPORT_PARAM_TYPE_TEXT,
	})
	if obj.PageSupport {
		params = append(params, &gmodel.ReportParam{
			AttributeName: "limit",
			Name:          "分页-limit",
			Type:          enums.REPORT_PARAM_TYPE_NUMBER,
		})
		params = append(params, &gmodel.ReportParam{
			AttributeName: "offset",
			Name:          "分页-offset",
			Type:          enums.REPORT_PARAM_TYPE_NUMBER,
		})
	}
	return params, nil
}

func (r *reportResolver) RequestReportParams(ctx context.Context, obj *model.Report) ([]*gmodel.ReportParam, error) {
	db := gorms.GetDb(ctx, r.Db)
	if obj == nil {
		return nil, nil
	}
	return r.ReportSrv.GetParamByReportId(ctx, db, *obj)
}

func (r *reportResolver) ReportAggregates(ctx context.Context, obj *model.Report) ([]*model.ReportAggregate, error) {
	db := gorms.GetDb(ctx, r.Db)
	if obj == nil || (*obj).Type != enums.REPORT_TYPE_AGGREGATE {
		return []*model.ReportAggregate{}, nil
	}
	aggregates, err := r.ReportAggregateSrv.GetByReportId(ctx, db, obj.ReportId)
	if err != nil {
		return nil, ferror.WrapWithCode("获取报表聚合信息异常", resultcode.FAIL, err)
	}
	return aggregates, nil
}

func (r *reportFormResolver) DictCategoryName(ctx context.Context, obj *model.ReportForm) (*string, error) {
	if obj == nil {
		return nil, nil
	}
	if obj.DictCategoryId == nil {
		return nil, nil
	}
	category, err := r.DictCategorySrv.GetByCategoryId(ctx, *obj.DictCategoryId)
	if err != nil {
		return nil, err
	}
	if category == nil {
		return nil, nil
	}
	return &category.CategoryName, nil
}

func (r *reportResultColumnResolver) DictCategoryName(ctx context.Context, obj *model.ReportResultColumn) (*string, error) {
	if obj == nil {
		return nil, nil
	}
	if obj.DictCategoryId == nil {
		return nil, nil
	}
	category, err := r.DictCategorySrv.GetByCategoryId(ctx, *obj.DictCategoryId)
	if err != nil {
		return nil, err
	}
	if category == nil {
		return nil, nil
	}
	return &category.CategoryName, nil
}

func (r *reportResultColumnResolver) JumpParams(ctx context.Context, obj *model.ReportResultColumn) ([]*model.ReportResultColumnJumpParam, error) {
	if obj == nil {
		return nil, nil
	}
	params := obj.JumpParams
	if params == nil {
		return nil, nil
	}
	jumpParams := make([]*model.ReportResultColumnJumpParam, 0)
	bytes, err := params.MarshalJSON()
	if err != nil {
		return nil, ferror.Wrap(resultcode.FAIL, err)
	}
	err = json.Unmarshal(bytes, &jumpParams)
	if err != nil {
		return nil, ferror.Wrap(resultcode.FAIL, err)
	}
	return jumpParams, nil
}

// Query returns QueryResolver implementation.
func (r *Resolver) Query() QueryResolver { return &queryResolver{r} }

// Report returns ReportResolver implementation.
func (r *Resolver) Report() ReportResolver { return &reportResolver{r} }

// ReportForm returns ReportFormResolver implementation.
func (r *Resolver) ReportForm() ReportFormResolver { return &reportFormResolver{r} }

// ReportResultColumn returns ReportResultColumnResolver implementation.
func (r *Resolver) ReportResultColumn() ReportResultColumnResolver {
	return &reportResultColumnResolver{r}
}

type queryResolver struct{ *Resolver }
type reportResolver struct{ *Resolver }
type reportFormResolver struct{ *Resolver }
type reportResultColumnResolver struct{ *Resolver }
